package com.envper.common.service.device.impl;

import com.envper.common.domain.device.Payload;
import com.envper.common.domain.dto.DeviceDto;
import com.envper.common.service.device.DeviceThresholdService;
import com.envper.mysql.base.service.DeviceLogBaseService;
import com.envper.mysql.domain.Status;
import com.envper.mysql.domain.entity.TDevice;
import com.envper.common.exception.GlobalException;
import com.envper.common.mapper.DeviceMapper;
import com.envper.common.service.device.DeviceService;
import com.envper.common.util.IdUtils;
import com.envper.mysql.base.service.DeviceBaseService;
import com.envper.mysql.domain.entity.TDeviceLog;
import com.mybatisflex.core.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

@Service
@RequiredArgsConstructor
public class DeviceServiceImpl implements DeviceService {
    private final DeviceBaseService deviceBaseService;
    private final DeviceLogBaseService deviceLogBaseService;
    private final DeviceThresholdService deviceThresholdService;

    @Override
    public List<DeviceDto> getDeviceInfoList() {
        List<TDevice> tDeviceList = deviceBaseService.list();
        return DeviceMapper.INSTANCE.toDeviceDtoList(tDeviceList);
    }

    @Override
    public void registerDeviceInfo(DeviceDto deviceDto) {
        TDevice tDevice = DeviceMapper.INSTANCE.toTDevice(deviceDto);
        tDevice.setId(IdUtils.createId());
        tDevice.setCreated(LocalDateTime.now());
        tDevice.setUpdated(LocalDateTime.now());
        boolean save = deviceBaseService.save(tDevice);
        if (!save) throw new GlobalException(Status.RegisterError);
    }

    @Override
    public void removeDeviceInfo(Long id) {
        boolean removed = deviceBaseService.removeById(id);
        if (!removed) throw new GlobalException(Status.REMOVEERROR);
    }

    @Override
    @Transactional
    public void saveData(Payload payload) {
        boolean exists = deviceBaseService.exists(new QueryWrapper().eq("id", payload.getDeviceId()));
        if (exists) {
            TDevice tDevice = TDevice.builder()
                    .id(payload.getDeviceId())
                    .temperature(payload.getTemperature())
                    .humidity(payload.getHumidity())
                    .lightMagnitude(payload.getLightMagnitude())
                    .h2s(payload.getH2s())
                    .updated(LocalDateTime.now())
                    .build();
            deviceBaseService.updateById(tDevice);
            TDeviceLog tDeviceLog = TDeviceLog.builder()
                    .id(IdUtils.createId())
                    .deviceId(payload.getDeviceId())
                    .humidity(payload.getHumidity())
                    .temperature(payload.getTemperature())
                    .lightMagnitude(payload.getLightMagnitude())
                    .h2s(payload.getH2s())
                    .uploadTime(LocalDateTime.now())
                    .build();
            deviceLogBaseService.save(tDeviceLog);
            deviceThresholdService.checkDeviceThreshold(payload);
        }
    }

    @Override
    public List<DeviceDto> getDeviceInfoListByDeviceIdList(List<Long> deviceList) {
        List<TDevice> tDeviceList = deviceBaseService.listByIds(deviceList);
        return DeviceMapper.INSTANCE.toDeviceDtoList(tDeviceList);
    }

    @Override
    public DeviceDto getDeviceInfoById(Long id) {
        TDevice tDevice = deviceBaseService.getById(id);
        return DeviceMapper.INSTANCE.toDeviceDto(tDevice);
    }
}
